package entity

import (
	"time"
	"xr-game-server/core/constants/common"
	"xr-game-server/core/constants/db"
	"xr-game-server/core/math"
	"xr-game-server/core/migrate"
	"xr-game-server/core/snowflake"
	"xr-game-server/core/syndb"
)

const (
	// TbUserRole 表名
	TbPlayerRole db.TbName = "player_roles"
)

// 列名
const (
	PlayerRoleServerId  db.TbCol = "server_id"
	PlayerRoleNick      db.TbCol = "nick"
	PlayerRoleAccountId db.TbCol = "account_id"
	PlayerRoleAvatarId  db.TbCol = "avatar_id"
	PlayerRoleExp       db.TbCol = "exp"
	PlayerRoleLevel     db.TbCol = "level"
	PlayerRoleGuildId   db.TbCol = "guild_id"
)

// PlayerInfo 玩家角色
type PlayerRole struct {
	migrate.OneModel
	ServerId  uint64 `gorm:"default:0;comment:区服id"`
	Nick      string `gorm:"default:'';comment:昵称"`
	AccountId uint64 `gorm:"default:0;comment:accountid"`
	AvatarId  uint32 `gorm:"default:0;comment:头像框id"`
	Exp       uint64 `gorm:"default:0;comment:经验"`
	Level     uint64 `gorm:"default:1;comment:等级"`
	GuildId   uint64 `gorm:"default:0;comment:公会id"`
}

func NewRole(accountId uint64) *PlayerRole {
	ret := &PlayerRole{}

	ret.ID = snowflake.GetId()
	ret.SetAccountId(accountId)
	ret.SetLevel(1)
	ret.SetCreatedAt(time.Now())
	ret.SetUpdatedAt(time.Now())
	return ret
}

func NewNullRole() *PlayerRole {
	ret := &PlayerRole{}
	return ret
}

func (receiver *PlayerRole) SetServerId(serverId uint64) {
	receiver.ServerId = serverId
	syndb.AddDataToLazyChan(TbPlayerRole, PlayerRoleServerId, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: serverId,
	})
}

func (receiver *PlayerRole) SetAccountId(accountId uint64) {
	receiver.AccountId = accountId
	syndb.AddDataToLazyChan(TbPlayerRole, PlayerRoleAccountId, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: accountId,
	})
}

func (receiver *PlayerRole) SetExp(exp uint64) {
	receiver.Exp = exp
	receiver.SetUpdatedAt(time.Now())
	syndb.AddDataToLazyChan(TbPlayerRole, PlayerRoleExp, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: exp,
	})
}

func (this *PlayerRole) AddExp(exp uint64, max uint64) {
	val := math.ChkMax(this.Exp, exp, max)
	this.SetExp(val + this.Exp)
}

func (receiver *PlayerRole) CanReduceExp() bool {
	return receiver.Exp > common.Zero
}

func (receiver *PlayerRole) ConsumeExp(exp uint64) bool {
	if receiver.Exp == common.Zero {
		return false
	}
	if receiver.Exp < exp {
		receiver.SetExp(common.Zero)
	} else {
		receiver.SetExp(receiver.Exp - exp)
	}
	return true
}

func (this *PlayerRole) AddLevel(level uint64) {
	val := math.ChkUInt64(this.Level, level)
	this.SetLevel(val + this.Level)
}

func (receiver *PlayerRole) SetLevel(level uint64) {
	receiver.Level = level
	receiver.SetUpdatedAt(time.Now())
	syndb.AddDataToLazyChan(TbPlayerRole, PlayerRoleLevel, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: level,
	})
}
func (receiver *PlayerRole) SetNick(nick string) {
	receiver.Nick = nick
	receiver.SetUpdatedAt(time.Now())
	syndb.AddDataToLazyChan(TbPlayerRole, PlayerRoleNick, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: nick,
	})
}

func (receiver *PlayerRole) SetAvatarId(avatarId uint32) {
	receiver.AvatarId = avatarId
	receiver.SetUpdatedAt(time.Now())
	syndb.AddDataToLazyChan(TbPlayerRole, PlayerRoleAvatarId, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: avatarId,
	})
}

func (receiver *PlayerRole) SetCreatedAt(val time.Time) {
	receiver.CreatedAt = val
	syndb.AddDataToLazyChan(TbPlayerRole, db.CreatedAtName, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: val,
	})
}

func (receiver *PlayerRole) SetUpdatedAt(val time.Time) {
	receiver.UpdatedAt = val
	syndb.AddDataToLazyChan(TbPlayerRole, db.UpdatedAtName, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: val,
	})
}
func (receiver *PlayerRole) SetGuildId(guildId uint64) {
	receiver.GuildId = guildId
	receiver.SetUpdatedAt(time.Now())
	syndb.AddDataToLazyChan(TbPlayerRole, PlayerRoleGuildId, &syndb.ColData{
		IdVal:  receiver.ID,
		ColVal: guildId,
	})
}

func initPlayerRole() {
	syndb.RegLazyWithSmall(TbPlayerRole, db.CreatedAtName)
	syndb.RegLazyWithSmall(TbPlayerRole, db.UpdatedAtName)

	syndb.RegLazyWithSmall(TbPlayerRole, PlayerRoleServerId)
	syndb.RegLazyWithSmall(TbPlayerRole, PlayerRoleNick)
	syndb.RegLazyWithSmall(TbPlayerRole, PlayerRoleAccountId)
	syndb.RegLazyWithSmall(TbPlayerRole, PlayerRoleAvatarId)
	syndb.RegLazyWithSmall(TbPlayerRole, PlayerRoleExp)
	syndb.RegLazyWithSmall(TbPlayerRole, PlayerRoleLevel)
	syndb.RegLazyWithSmall(TbPlayerRole, PlayerRoleGuildId)

	migrate.AutoMigrate(&PlayerRole{})
}
